import React from 'react';
import styles from './BasicLayout.less';
import _ from 'lodash';
import cls from 'classnames';
import { connect } from 'dva';
import { history } from 'umi';
// import { ConfigProvider } from 'antd';

// import 'antd/dist/antd.variable.min.css';

import { AUTH_URL_OBJ } from '../.././config/urlConfig';
// import appLogoImg from '@/assets/img/appLogo.png';
// components
import ProLayout from '@ant-design/pro-layout';
import { PageLoading, TRAlert, TRDefault, TRMessage } from '@/components';
import { default as TREditAppLogoModal } from '@/components/EditAppLogo';
import { default as AppBasicPopover } from '@/components/AppBasicPopover';
import MarqueeMenuItem from '@/components/MarqueeMenuItem';
import TRNotification from '@/utils/notification';
import { createFromIconfontCN, LeftCircleOutlined } from '@/utils/antdIcons';
// method
import Authorized from '@/utils/Authorized';
import {
  getToken,
  getAuthorityFromRoutes,
  getFanRuanSsoToken,
  setFanRuanSsoToken,
} from '@/utils/authority';
import analytics from '@/utils/analytics';
import emitter from '@/utils/events';
import renovate from '@/utils/renovate';
import jurisdiction from '@/utils/jurisdiction';
import { visitRecord } from '@/services/power';
import { MICRO_CONFIG } from '@/pages/Micro/helper';
import { jumpEdoc, queryFanRuanSsoToken } from '@/services/login';
import { HttpCode } from '@/utils/contacts';
import LayoutHeader from '@/components/LayoutHeader';
import { otherEnums } from '@/models/global';
import { findNodeByCodeBFS } from '@/utils/utils';
import { sendToChildWithAck } from '@/utils/childAppController';
import appLogoImg from './appLogo.png';

const handleMenu = (location, props) => {
  if (jurisdiction.PERMISSION_ARRAY.length === 0) {
    history.replace(`/404`);
    return {};
  }
  const currentPath = location.pathname;
  let isNoHas = true;
  const { appName, menuPush, visit } = props;
  let firstMenu =
    jurisdiction.PERMISSION_ARRAY.filter((n) => {
      if (currentPath == '/') {
        return n.menuId == visit.secondMenuId && n.customApplicationId == visit.customApplicationId;
      }
      return n.path === currentPath && n.customApplicationName == appName;
    })[0] || {};
  if (firstMenu.key === undefined && !['/user/login', '/personal', '/404'].includes(currentPath)) {
    firstMenu =
      jurisdiction.PERMISSION_ARRAY.filter(
        (n) => n.homePageFlag === true && n.customApplicationName == appName,
      )[0] || {};
    if (firstMenu.path === undefined) {
      firstMenu =
        jurisdiction.PERMISSION_ARRAY.filter(
          (n) =>
            (n.children === undefined || n.children?.length === 0) &&
            n.customApplicationName == appName,
        )[0] || {};
    }
    isNoHas = false;
    history.replace(`${firstMenu.path}`);
  }
  if (menuPush) {
    history.replace(`${firstMenu.path}${location.search ?? ''}`);
  }
  return {
    curPath: firstMenu.curPath,
    selectedKeys: [firstMenu.key],
    menuCode: firstMenu.menuCode,
    menuId: visit.secondMenuId,
    openKeys: [],
    pathUrl: `${firstMenu.path}${isNoHas ? location.search || '' : ''}`,
  };
};

@connect(({ user, global, loading }) => {
  return {
    iconUrl: user?.iconUrl || '',
    isFullScreen: global.isFullScreen || false,
    currentUser: user.currentUser,
    menuList: user.menuList || [],
    menuPerMission: user.menuPerMission || [],
    appName: user?.appName || '',
    appLogo: user?.appLogo || '',
    isLogo: user?.isLogo || false,
    menuLoading: user?.menuLoading || false,
    menuObj: user?.menuObj || {},
    visit: user?.visit || {},
    menuPush: user?.menuPush,
    changeMenuLoading: loading.effects['user/onMeunList'],
  };
})
export default class BasicLayout extends React.Component {
  constructor(props) {
    super(props);
    this.collapsedTimer = null;
    this.loopNumber = 0;
    const obj = handleMenu(this.props.location, props);
    localStorage.setItem('menuId', obj.menuId);
    this.state = {
      menuList: props.menuList || [],
      collapsed: true,
      selectedKeys: obj.selectedKeys || [],
      openKeys: [],
      pathUrl: obj.pathUrl,
      historyUnListenFN: null,
      menuId: obj.menuId,
    };
    renovate.isLOGOUT = false;
    props.dispatch({
      type: 'user/update',
      payload: { menuCode: obj?.menuCode, menuId: obj.menuId, curPath: obj?.curPath },
    });
  }

  static getDerivedStateFromProps(nextState, prevState) {
    const curPath = nextState.location.pathname;
    if (['/user/login', '/personal', '/404'].includes(curPath)) {
      return {
        selectedKeys: [],
        pathUrl: curPath,
      };
    }
    if (!_.isEqual(nextState.menuList, prevState.menuList)) {
      let obj = handleMenu(nextState.location, nextState);
      nextState.dispatch({
        type: 'user/update',
        payload: { menuCode: obj?.menuCode || '', curPath: obj?.curPath },
      });

      return {
        selectedKeys: obj.selectedKeys || [],
        menuList: [...nextState.menuList],
        pathUrl: obj.pathUrl,
      };
    }
    // 判断一下是点击or浏览器输入，防止多次执行
    const pathUrl = `${nextState.location.pathname}${nextState.location.search || ''}`;
    if (!_.isEqual(pathUrl, prevState.pathUrl) && !renovate.isTouched) {
      let obj = handleMenu(nextState.location, nextState);
      if (!_.isEqual(obj.selectedKeys, prevState.selectedKeys)) {
        nextState.dispatch({
          type: 'user/update',
          payload: { menuCode: obj?.menuCode || '', curPath: obj?.curPath },
        });
        return {
          selectedKeys: obj.selectedKeys || [],
          pathUrl: obj.pathUrl,
        };
      }
    }
    return null;
  }

  componentDidMount() {
    analytics.onInit();
    this.onFullscreenchange = () => {
      const isFullScreen = document.fullscreenElement ? true : false;
      this.setHeaderStyHei(isFullScreen);
      this.props.dispatch({
        type: 'global/update',
        payload: { isFullScreen },
      });
    };
    this.timerInterval = setInterval(() => {
      this.loopNumber = this.loopNumber + 1;
      if (this.loopNumber > 100) {
        this.loopNumber = 0;
      }
      this.onCheckFeedList(this.loopNumber % 4 === 0);
    }, 1000 * 60);
    document.addEventListener('fullscreenchange', this.onFullscreenchange);
    /* this.setState({
      historyUnListenFN: history.listen(this.historyListener.bind(this)),
    }); */
    this.collapsedTimer = setTimeout(() => {
      emitter.emit('onChangeMnue', this.state.collapsed);
    }, 200);
  }

  componentWillUnmount() {
    clearTimeout(this.collapsedTimer);
    analytics.onClearTimer();
    TRNotification.clear();
    this.timerInterval && clearInterval(this.timerInterval);
    this.props.dispatch({
      type: 'global/update',
      payload: { isFullScreen: false },
    });
    document.removeEventListener('fullscreenchange', this.onFullscreenchange);
    // this.state.historyUnListenFN();
    /* this.setState({
      historyUnListenFN: null,
    }); */
  }
  // history监听
  historyListener({ pathname }) {
    const menu = jurisdiction.getMenuItem(pathname);
    if (menu) {
      const notNeedAIApps = ['tianji', 'titanic'];
      const currentMenuInfo = MICRO_CONFIG[menu.menuCode] || {};
      const currentAIDom = document.getElementById('fastgpt-chatbot-button');
      // 隐藏或显示AI相关内容
      const display = notNeedAIApps.includes(currentMenuInfo.name) ? 'none' : 'block';
      currentAIDom.style.setProperty('display', display, 'important');
    }
  }

  // 调查问卷
  async onCheckFeedList(isCheckFeed) {
    if (window.__TRDEBUG__) {
      clearInterval(this.timerInterval);
    }
    jurisdiction.onUserCheckFeedList(isCheckFeed);
  }

  genJumpPath(menuCode, path) {
    let jumpPath = path;
    switch (menuCode) {
      case 'powerDistributionConfig':
        jumpPath = `${path}?notEam=1`;
        break;

      case 'KeShiHuaTaiZhangWeb':
        jumpPath = '/powerDistributionConfig';
        break;

      default:
        break;
    }

    return jumpPath;
  }

  async onMenuClick(menuItem) {
    const { path = '', menuCode = '' } = menuItem ?? {};
    const findNode = findNodeByCodeBFS(menuCode);
    if (findNode?.perms === '1') {
      window.open(`${window.location.origin}/#/saas${path}`);
      return;
    }

    // 微服务配置
    const { target = '' } = MICRO_CONFIG?.[menuCode] ?? {};
    const isJumpPath = path && target === '_blank';
    const isFanruanPath = path.indexOf('/fanruan/') === 0;
    // 操作日志
    const itemRecord = {
      customApplicationId: menuItem?.customApplicationId ?? '',
      firstMenuId: menuItem?.firstMenuId ?? '',
      secondMenuId: menuItem?.secondMenuId ?? '',
    };
    // 跳转
    if (isJumpPath || isFanruanPath) {
      visitRecord(itemRecord);
      return window.open(`${window.location.origin}/#/saas${path}`);
    }
    if (path === '/smart/zhiNengBaoBiao') {
      let ssoToken = getFanRuanSsoToken();
      const response = await queryFanRuanSsoToken();
      if (response.statusCode === HttpCode.SUCCESS && response.encrypt) {
        ssoToken = response.ssoToken;
      } else {
        TRMessage.error(response.message || '请求失败，请稍后再试');
        return;
      }
      return window.open('https://bi.gw-ams.com/webroot/decision?ssoToken=' + ssoToken);
    }
    if (path === '/Nextcloud') {
      const url = AUTH_URL_OBJ[CLIENT_ENV] || AUTH_URL_OBJ.release;
      if (!url) return TRMessage.warn('暂未配置跳转链接');
      return window.open(url);
    }

    if (path === '/edocJump') {
      const res = await jumpEdoc();
      if (res?.statusCode === HttpCode.SUCCESS) {
        return window.open(res.data);
      } else {
        TRMessage.error(res.message || '请求失败，请稍后再试');
        return;
      }
    }

    // 上传logo modal
    if (path === '/logoWEB') {
      return this.handleLogo();
    }
    // 离开询问
    let renovateRes = { index: 1 };
    if (renovate.isRenovate) {
      renovateRes = await TRAlert.show('当前工作将不被保存，继续执行此操作？');
    }
    if (renovateRes.index === 1 && this.props.dispatch) {
      if (renovate.isRenovate) {
        await sendToChildWithAck({ type: 'UNLOCK_APP' });
        renovate.isRenovate = false;
      }
      if (menuItem.isChildren) {
        // 路由切换
        const jumpPath = this.genJumpPath(menuCode, path);
        renovate.isTouched = true;
        visitRecord(itemRecord);
        localStorage.setItem('menuId', menuItem.secondMenuId);
        this.setState(
          {
            pathUrl: jumpPath,
            selectedKeys: [menuItem?.key || ''],
            menuCode: menuItem.menuCode,
            menuId: menuItem.secondMenuId,
          },
          () => {
            renovate.isTouched = false;
          },
        );
        this.props.dispatch({
          type: 'user/update',
          payload: {
            curPath: menuItem?.curPath || '',
            menuCode: menuItem?.menuCode || '',
            menuPush: false,
            menuId: menuItem.secondMenuId,
          },
        });
        history.push(jumpPath);
      }
    }
  }

  // 编辑logo
  handleLogo() {
    const { appLogo, isLogo } = this.props;
    if (!isLogo) return;
    TREditAppLogoModal.show({ appLogo });
  }

  // 展开收起
  toogleMenu() {
    const collapsed = !this.state.collapsed;
    this.setState({ collapsed });
    emitter.emit('onChangeMnue', collapsed);
  }

  // 根据是否全屏修改header高（变量）
  setHeaderStyHei(isFull) {
    const htmlDom = window.document.querySelector('html');
    const headerKey = '--global_HeaderBarHei';
    htmlDom.style.setProperty(headerKey, isFull ? '0px' : otherEnums[headerKey]);
  }

  render() {
    const {
      menuPerMission,
      children,
      isFullScreen,
      appName,
      menuLoading = false,
      menuList = [],
      iconUrl = '',
    } = this.props;
    const { collapsed, selectedKeys, openKeys } = this.state;
    const pathname = this?.props?.location?.pathname || '/';
    const authorized = getAuthorityFromRoutes(menuPerMission, pathname.replace('#', ''));
    const MyIcon = createFromIconfontCN({ scriptUrl: iconUrl });

    const layoutProps = {
      navTheme: 'dark',
      layout: 'side',
      contentWidth: 'Fluid',
      title: '交易辅助决策系统',
      className: styles.layout,
      colorWeak: false,
      pwa: false,
      fixSiderbar: false,
      logo: false,
      collapsed: collapsed,
      collapsedButtonRender: false,
      headerRender: false,
      disableMobile: true,
    };
    if (isFullScreen) {
      layoutProps.menuRender = false;
    }

    const menu = {
      locale: false,
      loading: menuLoading,
    };
    const menuProps = {
      subMenuCloseDelay: 0.1,
      subMenuOpenDelay: 0,
      inlineIndent: 0,
      openKeys: openKeys,
      selectedKeys: selectedKeys,
      onOpenChange: (keys = []) => {
        if (!this.state.collapsed) {
          // 手风琴模式（二三级）
          const currentOpenKey = keys[keys.length - 1] || '';
          const [appKey, level1Key] = currentOpenKey.split('-');
          const filterKeys = keys.filter((k) => {
            // 一级
            let currentKeys = keys.filter((i) => i.startsWith(appKey) && i.split('-').length === 3);

            currentKeys = currentKeys.filter((i) => i.split('-')[1] === level1Key);
            if (currentKeys.length > 1) {
              const delKey = currentKeys[0];
              return k !== delKey;
            }
            return true;
          });
          this.setState({ openKeys: [...filterKeys] });
        } else {
          this.setState({ openKeys: [...keys] });
        }
      },
    };

    const menuItemRender = (itemProps, defaultDom) => (
      <a
        href={`/saas/#/${itemProps.component}`}
        style={{ width: '100%' }}
        onClick={(e) => {
          e.preventDefault();
          this.onMenuClick(itemProps);
        }}
      >
        <MarqueeMenuItem styles={{ zIndex: 999 }}>{defaultDom}</MarqueeMenuItem>
      </a>
    );

    const menuHeaderRender = () => (
      <div
        className={cls({
          [styles.head]: true,
          [styles.collapsed]: this.state.collapsed,
        })}
      >
        <div className={styles.logo} onClick={this.handleLogo.bind(this)}>
          <img src={this.props.appLogo || appLogoImg} />
          {/* <img src={logo} alt="logo" /> */}
        </div>
        <div className={styles.btn} onClick={this.toogleMenu.bind(this)}>
          <LeftCircleOutlined />
        </div>
      </div>
    );

    const submenuItemRender = (item, dom) => (
      <div className="maqueen" style={{ display: 'flex', alignItems: 'center', width: '100%' }}>
        {item.icon && <span className="menu-icon">{item.icon}</span>}
        <MarqueeMenuItem>{item.name}</MarqueeMenuItem>
      </div>
    );

    const menuExtraRender = ({ collapsed }) => (
      <div
        className={cls({
          [styles.extra]: true,
          [styles.collapsed]: collapsed,
        })}
      >
        <div className={styles.title}>{appName}</div>
        <div className={styles.btn}>
          <AppBasicPopover />
        </div>
      </div>
    );

    const menuDataRender = (list) => {
      if (!list?.length) return [];
      return list.map((e) => ({
        key: e.key,
        parentKey: e.parentKey,
        name: e.name,
        curPath: e.curPath,
        path: e.path,
        url: e.url,
        menuCode: e.isChildren ? e.menuCode : '',
        customApplicationId: e.customApplicationId,
        firstMenuId: e.firstMenuId,
        secondMenuId: e.secondMenuId,
        component: e.component,
        icon: e?.icon ? <MyIcon type={e.icon} /> : null,
        isChildren: e.isChildren,
        isEam: e.isEam,
        children: menuDataRender(e?.children),
        // popupOffset: [0, -4],
      }));
    };

    return (
      <ProLayout
        {...this.props}
        {...layoutProps}
        menu={menu}
        menuProps={menuProps}
        menuDataRender={() => menuDataRender(menuList, iconUrl)}
        menuItemRender={menuItemRender}
        subMenuItemRender={submenuItemRender}
        menuExtraRender={menuExtraRender}
        menuHeaderRender={menuHeaderRender}
      >
        {/* <ConfigProvider> */}
        <LayoutHeader menuList={menuList} />
        <Authorized
          authority={authorized}
          currentAuthority={authorized}
          noMatch={!!this.props.currentUser ? null : <TRDefault type="error" />}
        >
          {this.props.changeMenuLoading ? (
            <div style={{ width: '100%', height: '100%' }}>
              <PageLoading />
            </div>
          ) : (
            children
          )}
        </Authorized>
        {/* </ConfigProvider> */}
      </ProLayout>
    );
  }
}
